<template>
  <div class="page-wrapper">
    <!-- 页面头部 -->
    <div class="page-header">
      <span class="text-primary font-bold">流程设计</span>
      <el-button type="primary" @click="handleCreate">新建流程</el-button>
    </div>

    <!-- 页面内容 -->
    <div class="page-content">
      <!-- 搜索表单 -->
      <el-form :inline="true" :model="searchForm" class="search-form">
        <el-form-item label="流程名称">
          <el-input v-model="searchForm.name" placeholder="请输入流程名称" clearable />
        </el-form-item>
        <el-form-item label="流程分类">
          <el-select v-model="searchForm.category" placeholder="请选择分类" clearable>
            <el-option
              v-for="item in categoryOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleSearch">查询</el-button>
          <el-button @click="resetSearch">重置</el-button>
        </el-form-item>
      </el-form>

      <!-- 表格区域 -->
      <div class="table-wrapper">
        <el-table v-loading="loading" :data="tableData">
          <el-table-column prop="name" label="流程名称" min-width="100" show-overflow-tooltip />
          <el-table-column prop="category" label="流程分类" min-width="100" show-overflow-tooltip>
            <template #default="{ row }">
              {{ getCategoryName(row.category) }}
            </template>
          </el-table-column>
          <el-table-column prop="key" label="流程标识" min-width="100" show-overflow-tooltip />
          <el-table-column prop="version" label="当前版本" width="160" align="center">
            <template #default="{ row }">
              <el-tag type="draft" size="small">
                {{ 'V' + row.version }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column prop="status" label="状态" width="100" align="center">
            <template #default="{ row }">
              <el-tag :type="getStatusType(row.status)" size="small">
                {{ getStatusLabel(row.status) }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column prop="createTime" label="创建时间" width="160" show-overflow-tooltip />
          <el-table-column
            prop="deploymentTime"
            label="最新部署时间"
            width="160"
            show-overflow-tooltip
          />
          <el-table-column label="操作" width="360" align="center" fixed="right">
            <template #default="{ row }">
              <el-button type="warning" link @click="handleEdit(row)">修改</el-button>
              <el-button type="primary" link @click="handleDesign(row)">设计</el-button>
              <el-button type="success" link @click="handleDeploy(row)">发布</el-button>
              <el-button type="warning" link @click="handleViewDefinitions(row)"
                >查看定义</el-button
              >
              <el-button
                v-if="row.status === 'deployed' || row.status === 'invalid'"
                :type="row.status === 'invalid' ? 'success' : 'warning'"
                link
                @click="handleToggleState(row)"
              >
                {{ row.status === 'invalid' ? '激活' : '挂起' }}
              </el-button>
              <el-button type="danger" link @click="handleDelete(row)">删除</el-button>
              <el-button type="primary" link @click="handleStart(row)"> 发起 </el-button>
            </template>
          </el-table-column>
        </el-table>
      </div>

      <!-- 分页区域 -->
      <div class="pagination-wrapper">
        <el-pagination
          v-model:current-page="currentPage"
          v-model:page-size="pageSize"
          :page-sizes="[10, 20, 30, 50]"
          layout="total, sizes, prev, pager, next, jumper"
          :total="total"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>
    </div>

    <!-- 新建/编辑流程对话框 -->
    <el-dialog v-model="formDialogVisible" :title="isEdit ? '修改流程' : '新建流程'" width="500px">
      <el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
        <el-form-item label="流程名称" prop="name">
          <el-input v-model="form.name" placeholder="请输入流程名称" :disabled="isEdit" />
        </el-form-item>
        <el-form-item label="流程分类" prop="categoryId">
          <el-select v-model="form.category" placeholder="请选择分类" class="w-full">
            <el-option
              v-for="item in categoryOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="流程标识" prop="key">
          <el-input v-model="form.key" placeholder="请输入流程标识" :disabled="isEdit">
            <template #append>.bpmn</template>
          </el-input>
        </el-form-item>
        <el-form-item
          label="获取用户"
          prop="userFetchUrl"
          :rules="[{ type: 'url', message: '请输入有效的URL地址', trigger: 'blur' }]"
        >
          <el-input v-model="form.userFetchUrl" placeholder="请输入获取用户接口地址">
            <template #append>
              <el-tooltip content="用于获取外部用户信息的接口地址" placement="top">
                <el-icon><QuestionFilled /></el-icon>
              </el-tooltip>
            </template>
          </el-input>
        </el-form-item>
        <el-form-item
          label="任务回调"
          prop="taskCallbackUrl"
          :rules="[{ type: 'url', message: '请输入有效的URL地址', trigger: 'blur' }]"
        >
          <el-input v-model="form.taskCallbackUrl" placeholder="请输入任务回调地址">
            <template #append>
              <el-tooltip content="任务完成后的回调接口地址" placement="top">
                <el-icon><QuestionFilled /></el-icon>
              </el-tooltip>
            </template>
          </el-input>
        </el-form-item>
        <el-form-item label="备注">
          <el-input
            v-model="form.description"
            type="textarea"
            :rows="3"
            placeholder="请输入备注信息"
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="formDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="handleSubmit">确 定</el-button>
      </template>
    </el-dialog>

    <!-- 流程定义对话框 -->
    <el-dialog v-model="definitionDialogVisible" title="流程定义列表" width="1200px">
      <div class="definition-header">
        <div class="process-info">
          <span>流程名称：{{ currentProcess?.name }}</span>
          <span>流程标识：{{ currentProcess?.key }}</span>
        </div>
      </div>

      <el-table :data="definitionList" v-loading="definitionLoading">
        <el-table-column prop="id" label="定义ID" min-width="220" show-overflow-tooltip />
        <el-table-column prop="version" label="版本" width="80" align="center" />
        <el-table-column prop="deploymentId" label="发布ID" min-width="180" show-overflow-tooltip />
        <el-table-column
          prop="resourceName"
          label="资源名称"
          min-width="120"
          show-overflow-tooltip
        />
        <el-table-column prop="deploymentTime" label="发布时间" width="180" show-overflow-tooltip>
          <template #default="{ row }">
            {{ row.deploymentTime || '-' }}
          </template>
        </el-table-column>
        <el-table-column prop="suspensionState" label="状态" width="100" align="center">
          <template #default="{ row }">
            <el-tag :type="row.suspensionState === 2 ? 'danger' : 'success'">
              {{ row.suspensionState === 2 ? '已挂起' : '已激活' }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="120" fixed="right">
          <template #default="{ row }">
            <el-button type="primary" link @click="handleViewXml(row)">查看XML</el-button>
          </template>
        </el-table-column>
      </el-table>

      <!-- 添加分页组件 -->
      <div class="pagination-wrapper">
        <el-pagination
          v-model:current-page="definitionPage.currentPage"
          v-model:page-size="definitionPage.pageSize"
          :page-sizes="[10, 20, 30, 50]"
          :total="definitionPage.total"
          @size-change="handleDefinitionSizeChange"
          @current-change="handleDefinitionCurrentChange"
          layout="total, sizes, prev, pager, next, jumper"
        />
      </div>
    </el-dialog>

    <!-- XML预览对话框 -->
    <el-dialog v-model="xmlDialogVisible" title="流程XML" width="800px">
      <pre class="xml-content">{{ currentXml }}</pre>
    </el-dialog>

    <!-- 发起流程弹窗 -->
    <el-dialog
      v-model="startDialogVisible"
      title="发起流程"
      width="50%"
      :modal-append-to-body="false"
      class="start-process-dialog"
    >
      <ApiTester
        :url="`/workflow/process/start`"
        :initial-params="initialCode"
        @success="handleStartSuccess"
      />
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="startDialogVisible = false">关闭</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, watch } from 'vue'
import { useRouter } from 'vue-router'
import type { FormInstance } from 'element-plus'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
  getFlowModels,
  createFlowModel,
  updateFlowModel,
  deployModel,
  deleteModel,
} from '@/api/model'
import { getFlowDefinitions, updateDefinitionState, getDefinitionXml } from '@/api/definition'
import type { ModelForm, ModelVo, PageResult, ProcessDefinitionVo } from '@/types/process'
import { useDictOptions } from '@/utils/dict'
import { QuestionFilled } from '@element-plus/icons-vue'
import ApiTester from '@/components/ApiTester/index.vue'
import { generateNumericId } from '@/utils/generator'

const router = useRouter()

// 搜索表单
const searchForm = reactive({
  name: '',
  category: '',
})

// 获取流程分类字典选项
const { options: categoryOptions } = useDictOptions('bpmn_category')

// 表格数据
const tableData = ref<ModelVo[]>([])
const loading = ref(false)

// 分页
const currentPage = ref(1)
const pageSize = ref(10)
const total = ref(0)

// 加载数据
const loadData = async () => {
  loading.value = true
  try {
    const res = await getFlowModels({
      pageNo: currentPage.value,
      pageSize: pageSize.value,
      ...searchForm,
    })
    const { list: records, total: totalCount } = res.data as PageResult<ModelVo>
    tableData.value = records
    total.value = totalCount
  } catch (error) {
    console.error('加载流程模型列表失败:', error)
    ElMessage.error('加载流程模型列表失败')
  } finally {
    loading.value = false
  }
}

// 搜索
const handleSearch = () => {
  currentPage.value = 1
  loadData()
}

// 重置搜索
const resetSearch = () => {
  searchForm.name = ''
  searchForm.category = ''
  handleSearch()
}

// 新建流程
const handleCreate = () => {
  formDialogVisible.value = true
  // 重置表单
  form.name = ''
  form.category = ''
  form.key = ''
  form.description = ''
}

// 新建流程
const handleSubmit = async () => {
  if (!formRef.value) return
  await formRef.value.validate(async (valid) => {
    if (valid) {
      try {
        if (isEdit.value) {
          // 修改流程
          await updateFlowModel(form)
          ElMessage.success('修改成功')
        } else {
          // 新建流程
          await createFlowModel(form)
          ElMessage.success('创建成功')
        }
        formDialogVisible.value = false
        loadData()
      } catch (error) {
        console.error(error)
        ElMessage.error(isEdit.value ? '修改失败' : '创建失败')
      }
    }
  })
}

// 发布流程
const handleDeploy = async (row: ModelVo) => {
  try {
    await ElMessageBox.confirm('确认发布该流程吗？', '提示', {
      type: 'warning',
    })
    await deployModel(row.id)
    ElMessage.success('发布成功')
    loadData()
  } catch (error) {
    if (error !== 'cancel') {
      console.error('发布流程失败:', error)
      ElMessage.error('发布流程失败')
    }
  }
}

// 删除流程
const handleDelete = async (row: ModelVo) => {
  try {
    await ElMessageBox.confirm('确认删除该流程吗？', '提示', {
      type: 'warning',
    })
    await deleteModel(row.id)
    ElMessage.success('删除成功')
    loadData()
  } catch (error) {
    if (error !== 'cancel') {
      console.error('删除流程失败:', error)
      ElMessage.error('删除流程失败')
    }
  }
}

// 分页处理
const handleSizeChange = (val: number) => {
  pageSize.value = val
  loadData()
}

const handleCurrentChange = (val: number) => {
  currentPage.value = val
  loadData()
}

// 初始化
onMounted(() => {
  loadData()
})

// 对话框控制
const formDialogVisible = ref(false)
const formRef = ref<FormInstance>()

// 表单数据
const form = reactive<ModelForm>({
  id: '',
  name: '',
  category: '',
  key: '',
  description: '',
  userFetchUrl: '',
  taskCallbackUrl: '',
})

// 表单校验规则
const rules = {
  name: [{ required: true, message: '请输入流程名称', trigger: 'blur' }],
  category: [{ required: true, message: '请选择流程分类', trigger: 'change' }],
  key: [{ required: true, message: '请输入流程标识', trigger: 'blur' }],
}

// 获取状态标签类型
const getStatusType = (status: string) => {
  const map: Record<string, string> = {
    draft: 'info',
    deployed: 'success',
    invalid: 'danger',
  }
  return map[status] || 'info'
}

// 获取状态标签文本
const getStatusLabel = (status: string) => {
  const map: Record<string, string> = {
    draft: '草稿',
    deployed: '已发布',
    invalid: '已作废',
  }
  return map[status] || status
}

// 设计流程
const handleDesign = (row: ModelVo) => {
  router.push({
    path: '/process/design/editor',
    query: {
      id: row.id,
      name: row.name,
      key: row.key,
    },
  })
}

// 流程定义相关
const definitionDialogVisible = ref(false)
const definitionLoading = ref(false)
const currentProcess = ref<ModelVo | null>(null)
const definitionList = ref<ProcessDefinitionVo[]>([])
// 添加定义列表的分页数据
const definitionPage = reactive({
  currentPage: 1,
  pageSize: 10,
  total: 0,
})

// XML预览相关
const xmlDialogVisible = ref(false)
const currentXml = ref('')

// 查看流程定义
const handleViewDefinitions = async (row: ModelVo) => {
  currentProcess.value = row
  definitionDialogVisible.value = true
  definitionLoading.value = true

  try {
    const res = await getFlowDefinitions({
      pageNo: definitionPage.currentPage,
      pageSize: definitionPage.pageSize,
      key: row.key,
    })
    const { list, total } = res.data
    definitionList.value = list
    definitionPage.total = total
  } catch (error) {
    console.error('获取流程定义失败:', error)
    ElMessage.error('获取流程定义失败')
  } finally {
    definitionLoading.value = false
  }
}

// 定义列表分页变化
const handleDefinitionSizeChange = (val: number) => {
  definitionPage.pageSize = val
  if (currentProcess.value) {
    handleViewDefinitions(currentProcess.value)
  }
}

const handleDefinitionCurrentChange = (val: number) => {
  definitionPage.currentPage = val
  if (currentProcess.value) {
    handleViewDefinitions(currentProcess.value)
  }
}

// 查看XML
const handleViewXml = async (row: ProcessDefinitionVo) => {
  try {
    const res = await getDefinitionXml(row.id)
    currentXml.value = res.data.xmlStr || ''
    xmlDialogVisible.value = true
  } catch (error) {
    console.error('获取XML失败:', error)
    ElMessage.error('获取XML失败')
  }
}

// 获取分类名称
const getCategoryName = (code: string) => {
  const option = categoryOptions.value.find((opt) => opt.value === code)
  return option?.label || code
}

// 切换流程状态
const handleToggleState = async (row: ModelVo) => {
  const action = row.suspended ? '激活' : '挂起'
  try {
    await ElMessageBox.confirm(`确认${action}该流程吗？`, '提示', {
      type: 'warning',
    })
    await updateDefinitionState(row.processDefinitionId)
    ElMessage.success(`${action}成功`)
    // 重新加载列表
    loadData()
  } catch (error) {
    if (error !== 'cancel') {
      console.error(`${action}流程失败:`, error)
      ElMessage.error(`${action}流程失败`)
    }
  }
}

// 是否为编辑模式
const isEdit = ref(false)

// 编辑流程
const handleEdit = (row: ModelVo) => {
  isEdit.value = true
  form.id = row.id
  form.name = row.name
  form.category = row.category
  form.key = row.key
  form.description = row.description
  form.userFetchUrl = row.userFetchUrl || ''
  form.taskCallbackUrl = row.taskCallbackUrl || ''
  formDialogVisible.value = true
}

// 关闭对话框时重置表单
watch(formDialogVisible, (val) => {
  if (!val) {
    formRef.value?.resetFields()
    isEdit.value = false
  }
})

const startDialogVisible = ref(false)

// 编辑器引用
const initialCode = ref('')

// 发起流程
const handleStart = (row: ModelVo) => {
  currentProcess.value = row
  // 生成初始化参数
  initialCode.value = JSON.stringify(
    {
      userId: generateNumericId(),
      processKey: row.key,
      businessKey: generateNumericId(),
      variables: {
        applicant: '张三',
        amount: 1000,
        description: '报销申请',
      },
    },
    null,
    2,
  )

  startDialogVisible.value = true
}

// 处理发起成功
const handleStartSuccess = (res: any) => {
  if (res.code === 0) {
    ElMessage.success('发起成功')
    startDialogVisible.value = false
    // 刷新列表
    loadData()
  } else {
    ElMessage.error(res.msg || '发起失败')
  }
}
</script>

<style scoped>
.definition-header {
  background-color: var(--el-bg-color-page);
  border-radius: var(--el-border-radius-base);
  padding: var(--el-spacing-medium);
  margin-bottom: var(--el-spacing-medium);
}

.process-info {
  display: flex;
  gap: var(--el-spacing-large);
  color: var(--el-text-color-regular);

  span {
    display: flex;
    align-items: center;

    &::before {
      content: '';
      display: inline-block;
      width: 4px;
      height: 4px;
      margin-right: 8px;
      background-color: var(--el-color-primary);
      border-radius: 50%;
    }
  }
}

.xml-content {
  margin: 0;
  padding: var(--el-spacing-medium);
  background-color: var(--el-bg-color-page);
  border-radius: var(--el-border-radius-base);
  font-family: 'Fira Code', Consolas, monospace;
  font-size: 14px;
  line-height: 1.6;
  white-space: pre-wrap;
  overflow-x: auto;
}

.pagination-wrapper {
  margin-top: 16px;
  display: flex;
  justify-content: flex-end;
}

.editor-container {
  border: 1px solid #dcdfe6;
  border-radius: 4px;
}

.cm-component {
  font-family: monospace;
}

:deep(.start-process-dialog) {
  margin-top: 5vh !important;
}

:deep(.start-process-dialog .el-dialog__body) {
  max-height: 70vh;
  overflow-y: auto;
  padding: 0;
}
</style>
